//
// Created by Administrator on 2016/12/9.
//

#ifndef PROJECT_GAME_H
#define PROJECT_GAME_H

#include "Rubik.h"

#define MAXINSTANCENUM 50000
#define MAX_KEY_NUM 4
#define CubeSize 20.0f

class Game {
public:
    static std::default_random_engine DefaultRandomEngine;
    uint8_t holdingKeyNum = 0;

    btDiscreteDynamicsWorld *dynamicsWorld;
    btCollisionShape *boxCollisionShape;
    GLfloat mWidth, mHeight;
    SDL_Window *mSDLWindow;

    Game(const char *title, int32_t width, int32_t height);

    std::unordered_map<std::string, ZainTL::FileDatas> fileDatas;
    ZainGL::Model *cubeModel;
    ZainGL::Model *planeModel;
    ZainGL::Material *shadowMaterial, *shadowVisualMaterial, *skyMaterial,*meshMaterial;
    ZainGL::DirectionalLight *directionalLight;
    std::vector<ZainGL::Model*> models;
    std::vector<ZainGL::Material*> materials;
    std::vector<ZainGL::Light*> lights;
    CEGUI::OpenGL3Renderer *ceguiRenderer;
    ZainGL::Sky *sky;

    void reloadAsset();

    Rubik *mRubik;

    glm::mat4 projectionMat;
    glm::vec3 worldRight;
    ZainGL::Camera camera;
    GLfloat cameraKeyMoveSpeed=110.0f/1000;

    float frameTime = 1000.f / 60;
    float lastRenderTime = 0;
    float deltaTime = 0;

    int32_t holdingKeys[MAX_KEY_NUM];

    BTNPOINT rightButtonPressedPoint = {-1, -1};
    BTNPOINT virtualRightButtonPoint = {0}, lastVirtualRightButtonPoint = {0};
    float rightMouseSens = 0.0005f;

    Cube *clickedCube;
    float leftButtonSens = 0.0008f;
    BTNPOINT lastLeftButtonPoint{-1, -1};
    glm::vec3 leftButtonClickPosWorld = glm::vec3(-1);

    FACE mClickedFace;
    float PI = 3.14159265358979323846264338327950288;
    float PIm2 = PI * 2;
    float PId2 = PI / 2;
    float PId4 = PI / 4;

    void initBulletPhysics();

    void initCEGUI();

    bool shouldClose = false;

    void run();

    void resetRubik();

    void windowSizing(Sint32 width, Sint32 height);

    CEGUI::MouseButton SDLtoCEGUIMouseButton(const Uint8 &button);

    CEGUI::Key::Scan SDLtoCEGUIKey(SDL_Scancode key);

    SDL_GLContext mSDLContext;

    void SDLToCEGUITextUTF8(const char *utf8str);

    CEGUI::Window *popupMenu;
    CEGUI::Window *settingMenu;
    void updateDimenLabel(CEGUI::Window *dimenLabel, CEGUI::Slider *dimenSlider);

    void CEGUIKeyEventRootWindow(const CEGUI::EventArgs &args);

    GLuint autoMessCount;
    glm::vec3 cameraBegin,cameraEnd,cameraSpeed;
    GLfloat cameraTotalTime;
    void newGame(const CEGUI::EventArgs &args);

    CEGUI::Window *timeCountLabel;
    uint32_t lastCountTime=0;

    CEGUI::Window *fpsCountLabel;
    uint32_t fpsCount=0,lastCountFPSTime;

    CEGUI::Window *WinWindow;
};


#endif //PROJECT_GAME_H
